﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Mindfor.Web.Data
{
	/// <summary>
	/// Class for log data object.
	/// </summary>
	public class Log : IdEntity
	{
		/// <summary>
		/// Gets or sets log type.
		/// </summary>
		public virtual byte LogType { get; set; }

		/// <summary>
		/// Gets or sets log type.
		/// </summary>
		public virtual LogType Type
		{
			get { return LogTypes.Get(LogType); }
			set { LogType = value.Id; }
		}

		/// <summary>
		/// Gets or sets log date.
		/// </summary>
		public virtual DateTime Date { get; set; }

		/// <summary>
		/// Gets or sets short description.
		/// </summary>
		public virtual string ShortText { get; set; }

		/// <summary>
		/// Gets or sets description.
		/// </summary>
		public virtual string Description { get; set; }

		/// <summary>
		/// Initializes new instance.
		/// </summary>
		public Log()
		{
			Date = DateTime.UtcNow;
		}

		/// <summary>
		/// Initializes new instance with exception.
		/// </summary>
		/// <param name="ex">Exception.</param>
		public Log(Exception ex)
			: this()
		{
			Exception e = ex;
			StringBuilder sb = new StringBuilder();
			while (e != null)
			{
				if (sb.Length > 0)
					sb.Append("\r\n\r\n---Inner exception---");
				sb.Append(CreateErrorMessage(e));
				e = e.InnerException;
			}

			Type = LogTypes.Error;
			ShortText = ex.Message;
			Description = sb.ToString();
		}

		/// <summary>
		/// Initializes new instance.
		/// </summary>
		/// <param name="logType">Type of log message</param>
		/// <param name="shortLogMessage">Short massage</param>
		/// <param name="logDescription">Description</param>
		public Log(LogType logType, string shortLogMessage, string logDescription)
			: this()
		{
			Type = logType;
			ShortText = shortLogMessage;
			Description = logDescription;
		}

		/// <summary>
		/// Initializes new isntance with custom type name
		/// </summary>
		/// <param name="logTypeName">New log type name. This name must be registered in LogTypes.</param>
		public Log(string logTypeName)
			: this()
		{
			Type = LogTypes.Get(logTypeName);
			if (Type == null)
				throw new ArgumentException("Can not find LogType with name \"" + logTypeName + "\".");
		}

		/// <summary>
		/// Creates fiendly error message to write to log description.
		/// </summary>
		/// <param name="ex">Exception to create message for.</param>
		/// <returns>Fiendly error message.</returns>
		private string CreateErrorMessage(Exception ex)
		{
			return String.Format("Type: {0}\r\nMessage: {1}\r\nSource: {2}\r\nStack stace: {3}",
				ex.GetType().FullName, ex.Message, ex.Source, ex.StackTrace);
		}
	}
}
